#include "account_service.h"
#include "context.h"
#include "streamdata.h"
#include "log.h"
#include "1700_account.pb.h"


static bool __init__ = AccountService::Instance()->Init();

bool AccountService::Init()
{
    Ctx.msg_router.BindMsg(account_proto::ACCOUNT_CMD_GET_ACCOUNT_BY_UUID_RESP, std::bind(&AccountService::OnAccountGet, this, std::placeholders::_1));
    return true;
}

bool AccountService::HandleGetAccount(const std::string& agency, const std::string& name, std::string&& trans, std::uint64_t sence)
{
    log_debug("agency:%s,name:%s,sence:%llu", agency.c_str(),name.c_str(),sence);
    StreamData stream_data;
    StreamDataWriter write(stream_data);
    write.Write<std::uint64_t>(sence);
    write.WriteString(trans);

    account_proto::GetAccountByUuidReq req;
    req.set_agency(agency);
    req.set_username(name);
    req.set_trans(std::move(stream_data.Data()));
    return 0 == Ctx.host->MtSendtoSrv(account_proto::ACCOUNT_CMD_GET_ACCOUNT_BY_UUID_REQ, SERVER_TYPE_ACCOUNT, &req, 0);
}

void AccountService::OnAccountGet(MsgData&& data)
{
    do
    {
        account_proto::GetAccountByUuidResp resp;
        if (!resp.ParseFromArray(data.data.c_str(), data.data.size()))
        {
            log_error("parser account_proto::GetAccountByUuidResp failed, stype:%d,svid:%d,uuid:%d", data.svtype, data.svid, data.uuid);
            break;
        }

        StreamData stream_data(std::move(*resp.mutable_trans()));
        StreamDataReader reader(stream_data);
        std::uint64_t sence = reader.Read<std::uint64_t>();
        std::string trans = reader.ReadString();

        log_debug("sence:%llu,resp:%s", sence, resp.ShortDebugString().c_str());
        try
        {
            if (resp.err_code() == 0)
            {
                stAccount account;
                account.uid = resp.acc().uid();
                account.agency = resp.acc().agency();
                account.username = resp.acc().username();
                account.uuid = resp.acc().uuid();
                account.agency_id = resp.acc().agency_id();

                stAccount* p_account = AccountMgr::Instance()->Update(std::move(account));

                OnSenceAccountGet(sence, std::move(trans), resp.err_code(), p_account);
            }
            else
            {
                OnSenceAccountGet(sence, std::move(trans), resp.err_code(), nullptr);
            }
        }
        catch(const std::exception& e)
        {
            log_error("catch exception:%s, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", e.what(), sence, data.svtype, data.svid, data.uuid, resp.ShortDebugString().c_str());
        }
        catch(...)
        {
            log_error("catch unknown exception, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", sence, data.svtype, data.svid, data.uuid, resp.ShortDebugString().c_str());
        }
    } while(false);
}

void AccountService::OnSenceAccountGet(std::uint64_t sence, std::string&& trans, std::int32_t err_code, stAccount* account)
{
    auto it = m_account_get_listen.find(sence);
    if (it == m_account_get_listen.end())
    {
        log_warning("sence:%d not listen", sence);
        return;
    }
    it->second(err_code, account, std::move(trans));
}



